<?php
/**
 * 归因链接控制器
 */
namespace Frieza\Modules\AdServing\Controllers;

use App\Http\Controllers\Controller;
use App\Pockets\GridDataModel as pGridDataModel;
use Doraemon\model\AdServing\Assets;
use Doraemon\model\AdServing\AttributionLink;
use Doraemon\model\AdServing\Channel;
use Doraemon\model\ShortLink\ShortLink;
use Doraemon\service\AdServing\ChannelService;
use Doraemon\service\position\UserProfileModule\AdChannelChannel;
use Doraemon\tools\ParamsCheck;
use Encore\Admin\Facades\Admin;
use Encore\Admin\Grid;
use Encore\Admin\Layout\Content;
use Encore\Admin\Widgets\Form;
use Encore\Admin\Widgets\Tab;
use Illuminate\Http\Request;
use Illuminate\Support\MessageBag;

class AttributionLinkController extends Controller {
    const SHORT_PREFIX = 'http://l.hhz1.cn/';
    const PAGE_SIZE = 50;
    const CHANNEL_ONE_ID_SHARE = 7;

    public function index(Request $request, Content $content)
    {
        $request_params = $request->all();

        $pageSize = $request->input('per_page', self::PAGE_SIZE);
        $page = $request->input('page', 1);

        $condition = [];
        // 活动理由
        if (!empty($request_params['reason'])) {
            $condition['reason[~]'] = $request_params['reason'];
        }
        // 投放大类
        if (!empty($request_params['channel_one_id'])) {
            $condition['channel_one_id'] = $request_params['channel_one_id'];
        }
        // 投放渠道
        if (!empty($request_params['channel_two_id'])) {
            $condition['channel_two_id'] = $request_params['channel_two_id'];
        }
        // 投放位置
        if (!empty($request_params['channel_three_id'])) {
            $condition['channel_three_id'] = $request_params['channel_three_id'];
        }
        // 渠道编码
        if (!empty($request_params['channel_code'])) {
            $condition['channel_code[~]'] = $request_params['channel_code'];
        }
        // 原始链接
        if (!empty($request_params['origin_link'])) {
            $condition['origin_link[~]'] = $request_params['origin_link'];
        }
        $condition['data_status'] = AttributionLink::STATUS_NORMAL;
        $condition['ORDER'] = ['id' => 'DESC'];
        $condition['LIMIT'] = [
            ($page - 1) * $pageSize,
            $pageSize,
        ];
        $lists = AttributionLink::getListByCommonCondition($condition);
        foreach ($lists as &$aRow) {
            $aRow['qrcode'] = $aRow['short_link'];
        }
        unset($aRow);
        $total = AttributionLink::cntListByCommonCondition($condition);
        $gridModel = new pGridDataModel($lists, $total, [
            'perPage' => $pageSize
        ]);
        $listGrid = Admin::grid($gridModel, function (Grid $grid) use ($gridModel) {
                $grid->paginate($gridModel->getPerPage());
                $grid->disableExport();
                $grid->disableRowSelector();
                $grid->filter(function (Grid\Filter $filter) {
                    $filter->disableIdFilter();
                    $filter->column(1 / 2, function ($filter) {
                        $filter->equal('reason', '活动理由')->placeholder('请输入活动理由');
                        $filter->equal('channel_two_id', '投放渠道')
                            ->select(ChannelService::getChannelSelectOptionsByLevelWithCode(2))
                            ->load('channel_three_id', '/admin/adServing/serving/options/');
                        $filter->equal('channel_code', '渠道编码')->placeholder('请输入渠道编码');
                    });
                    $filter->column(1 / 2, function ($filter) {
                        $filter->equal('channel_one_id', '投放大类')
                            ->select(ChannelService::getChannelSelectOptionsByLevelWithCode(1))
                            ->load('channel_two_id', '/admin/adServing/serving/options/');
                        $filter->equal('channel_three_id', '投放位置')->select(ChannelService::getChannelSelectOptionsByLevelWithCode(3));
                        $filter->equal('origin_link', '原始链接')->placeholder('请输入原始链接');
                    });
                    $filter->expand();
                });
                $grid->column('id', 'id');
                $grid->column('reason', '活动理由')->width(150);
                $grid->column('channel_info', '投放信息')->display(function () {
                    return '<strong>[投放大类]:</strong>' . $this->channel_one_name.'('.$this->channel_one_code.')' . "<br>" .
                            '<strong>[投放渠道]:</strong>' . $this->channel_two_name.'('.$this->channel_two_code.')' . "<br>" .
                            '<strong>[投放位置]:</strong>' . $this->channel_three_name.'('.$this->channel_three_code.')';
                })->width(300);
                $grid->column('channel_code', '渠道编码')->width(150);
                $grid->column('add_date', '创建时间')->display(function () {
                    return date('Y-m-d H:i:s', $this->add_time);
                })->width(100);
                $grid->column('qrcode', '二维码(短)')->newQrcode()->width(100);
                $grid->column('short_link', '短链接')->width(100)->copyable();
                $grid->column('target_link', '归因链接')->width(300)->copyable();
                $grid->column('origin_link', '原始链接')->width(300)->copyable();
                $grid->actions(function (Grid\Displayers\Actions $actions) {
                    $actions->disableEdit();
                    $actions->disableView();
                });
            }
        );
        $tips = [];
        return $content
            ->header('归因链接管理')
            ->row($tips)
            ->row($listGrid);
    }

    public function edit(Content $content, int $id = 0): Content {
        Admin::script($this->setScript());
        $tab = new Tab();
        $form = new Form();

        $form->url('origin_link', '原始链接')
            ->required()
            ->placeholder()
            ->append("<a id='preview' target='_blank'>预览</a>");

        $form->select('channel_one_id', '投放大类(media_source)')
            ->required()
            ->options(ChannelService::getChannelSelectOptionsByLevelWithCode(1))
            ->load('channel_two_id', '/admin/adServing/attribution/options/');

        $form->select('channel_two_id', '投放渠道(channel)')
            ->required()
            ->options(ChannelService::getChannelSelectOptionsByLevelWithCode(2))
            ->load('channel_three_id', '/admin/adServing/attribution/options/');

        $form->select('channel_three_id', '投放位置(location)')
            ->required()
            ->options(ChannelService::getChannelSelectOptionsByLevelWithCode(3));

        $form->text('channel_code', '渠道编码(detail_name)')
            ->required()
            ->placeholder('请填写渠道编码(渠道编码是唯一的不允许重复)')
            ->help('对外分享页时自动生成，请注意会有一定延迟！');

        $form->select('asset_type_id', '素材类型(page_type)')->options(Assets::getInfoByFieldWithCode('page_type'));
        $form->text('asset_form', '素材形式(adset)')->placeholder('请填写素材形式');
        $form->text('asset_theme', '素材主题(sub_param_1)')->placeholder('请填写素材主题');
        $form->text('asset_space', '素材空间(sub_param_2)')->placeholder('请填写素材空间');
        $form->text('asset_element', '素材元素(sub_param_3)')->placeholder('请填写素材元素');
        $form->text('reason', '活动理由')->readonly();

        $form->html('
            <label id="generateTargetLink" class="btn-info" style="float:left;padding: 10px;border-radius: 5px;">归因链接生成</label>
            <label id="copyTargetLink" class="btn-default" style="float: right;padding: 10px;border-radius: 5px;">复制归因链接</label>
        ');
        $form->textarea('target_link', '归因链接')->placeholder('此处会根据上述参数生成归因链接～')->readonly();
        $form->action('/admin/adServing/attribution/save');
        $title = "创建归因链接";
        $tab->add($title, $form);
        return $content->header('归因链接管理')
            ->breadcrumb(
                [
                    'text' => '归因链接列表',
                    'url' => '/adServing/attribution'
                ],
                ['text' => "$title"]
            )
            ->body($tab);
    }

    // 监听文本变化
    private function setScript() {
        $iChannelOneIdShare = self::CHANNEL_ONE_ID_SHARE;
        return <<<SCRIPT
            // 原始链接预览
            $('#preview').click(function() {
                $(this).attr('href', $('#origin_link').val());
            });
            
            // 复制链接
            $.getScript('/vendor/js/clipboard/dist/clipboard.min.js', function(){
            // 避免pjax重复加载js导致事件重复绑定
                if (typeof (pjax_isLoad) != "undefined") {
                    return;
                } 
                pjax_isLoad = true;
                let copyBtn = new ClipboardJS("#copyTargetLink", {
                    text: function(e) {
                        return $(e).parent().parent().parent().find('.target_link').val();
                    }
                });
                copyBtn.on("success",function(e){
                    // 复制成功
                    if (e.text.length > 0) {
                        toastr.success('复制成功');
                    }
                    e.clearSelection();
                });
                copyBtn.on("error",function(e){
                    //复制失败
                    console.log( e.action )
                });
            });
            $("button[type='reset']").click(function(){
                $("select[name='channel_one_id']").select2('val', 'All');
            });
        
            // 必传参数手动输入原始链接、渠道编码监听
            $('#origin_link').add('#channel_code').on('input propertychange', function() {
                // 归因链接
                $('textarea[name="target_link"]').val(getTargetLink());
            });
            
            $('select[name="channel_one_id"]').add('select[name="channel_two_id"]')
                .add('select[name="channel_three_id"]').on('change', function() {
                // 对外分享自动生成渠道编码
                var channelOneId = $('select[name="channel_one_id"] option:selected').val();
                if (channelOneId == $iChannelOneIdShare) {
                    var url = '/admin/adServing/attribution/getChannelCode';
                    $.post(url, [], function (result) {
                        console.log(result)
                        if (result.status == false) {
                            layer.msg(result.message);
                            return false;
                        } else {
                            // 防止元素未加载出来，取不到数据
                            setTimeout(function(){
                                var channelOneFullName = $('select[name="channel_one_id"] option:selected').text();
                                var channelOneCode = channelOneFullName.slice(channelOneFullName.indexOf('(') + 1, channelOneFullName.indexOf(')'));
                                var channelTwoFullName = $('select[name="channel_two_id"] option:selected').text();
                                var channelTwoCode = channelTwoFullName.slice(channelTwoFullName.indexOf('(') + 1, channelTwoFullName.indexOf(')'));
                                var channelThreeFullName = $('select[name="channel_three_id"] option:selected').text();
                                console.log('对外分享：'+channelThreeFullName);
                                var channelThreeCode = channelThreeFullName.slice(channelThreeFullName.indexOf('(') + 1, channelThreeFullName.indexOf(')'));
                                var channelCode = channelOneCode + '-' + channelTwoCode + '-' + channelThreeCode + '-' + result.data;
                                $('#channel_code').attr('readonly', 'readonly').val(channelCode);
                            },300);
                        }
                    });
                } else {
                    $('#channel_code').attr('readonly', false).val('');
                }
                // 归因链接
                setTimeout(function(){
                    $('textarea[name="target_link"]').val(getTargetLink());
                }, 500);
            });
            
            // 非必传参数手动输入监听
            $('#asset_form').add('#asset_theme')
                            .add('#asset_space')
                            .add('#asset_element')
                            .on('input propertychange', function() {
                var pageTypeFullName = $('select[name="asset_type_id"] option:selected').text();
                var pageTypeCode = pageTypeFullName.slice(0, pageTypeFullName.indexOf('('));
                var assetForm = $('#asset_form').val();
                var assetTheme = $('#asset_theme').val();
                var assetSpace = $('#asset_space').val();
                var assetElement = $('#asset_element').val(); 
                // 活动理由 
                $('#reason').val(getReason(pageTypeCode, assetForm, assetTheme, assetSpace, assetElement));
                // 归因链接
                $('textarea[name="target_link"]').val(getTargetLink());
            });
            
            $('#generateTargetLink').click(function() {
                var originLink = $('#origin_link').val();
                var channelOneId = $('select[name="channel_one_id"] option:selected').val();
                var channelTwoId = $('select[name="channel_two_id"] option:selected').val();
                var channelThreeId = $('select[name="channel_three_id"] option:selected').val();
                var channelCode = $('#channel_code').val();
                if (originLink == '') {
                    layer.msg('未填写"原始链接"');
                    return false;
                }
                if (channelOneId == '') {
                    layer.msg('未选择"渠道名称(media source)"');
                    return false;
                }
                if (channelCode == '') {
                    layer.msg('未填写"渠道编码(detail name)"');
                    return false;
                }
                if (channelTwoId == '') {
                    layer.msg('未选择"投放渠道(channel)"');
                    return false;
                }
                if (channelTwoId == '') {
                    layer.msg('未选择"投放位置(location)"');
                    return false;
                }
                $('textarea[name="target_link"]').val(getTargetLink());
            });
            
            // 非必传参数下拉选框监听
            $('select[name="asset_type_id"]').on('change', function() {
                var pageTypeFullName = $('select[name="asset_type_id"] option:selected').text();
                var pageTypeCode = pageTypeFullName.slice(0, pageTypeFullName.indexOf('('));
                var assetForm = $('#asset_form').val();
                var assetTheme = $('#asset_theme').val();
                var assetSpace = $('#asset_space').val();
                var assetElement = $('#asset_element').val();
                // 活动理由 
                $('#reason').val(getReason(pageTypeCode, assetForm, assetTheme, assetSpace, assetElement));
                // 归因链接
                $('textarea[name="target_link"]').val(getTargetLink());
            });
            
            
            // 获取活动理由
            function getReason(assetType, assetForm, assetTheme, assetSpace, assetElement) {
                var reason = '';
                if (assetType != '') {
                    reason += '-' + assetType;
                }
                if (assetForm != '') {
                    reason += '-' + assetForm;
                }
                if (assetTheme != '') {
                    reason += '-' + assetTheme;
                }
                if (assetSpace != '') {
                    reason += '-' + assetSpace;
                }
                if (assetElement != '') {
                    reason += '-' + assetElement;
                }
                return reason.slice(1);
            }
            
            // 获取归因链接
            function getTargetLink() {
                // 原始链接
                originLink = $('#origin_link').val();
                // 获取投放大类、投放渠道、投放位置的code
                channelOneFullName = $('select[name="channel_one_id"] option:selected').text();
                channelOneCode = channelOneFullName.slice(channelOneFullName.indexOf('(') + 1, channelOneFullName.indexOf(')'));
                channelTwoFullName = $('select[name="channel_two_id"] option:selected').text();
                channelTwoCode = channelTwoFullName.slice(channelTwoFullName.indexOf('(') + 1, channelTwoFullName.indexOf(')'));
                channelThreeFullName = $('select[name="channel_three_id"] option:selected').text();
                channelThreeCode = channelThreeFullName.slice(channelThreeFullName.indexOf('(') + 1, channelThreeFullName.indexOf(')'));
                // 渠道编码
                channelCode = $('#channel_code').val();
                // 组织拼接参数
                // 1. 必传参数
                let mustParams = {
                    media_source: channelOneCode,
                    detail_name: channelCode,
                    channel: channelTwoCode,
                    location: channelThreeCode,
                };
                console.log(mustParams);
                mustParamsQ = $.param(mustParams)
                console.log('拼接后的must_params_query:'+mustParamsQ);
                // 2. 可选参数
                let optionalParams = {};
                pageTypeFullName = $('select[name="asset_type_id"] option:selected').text();
                pageTypeCode = pageTypeFullName.slice(pageTypeFullName.indexOf('(') + 1, pageTypeFullName.indexOf(')'));
                adset = $('#asset_form').val();
                sub_param1 = $('#asset_theme').val();
                sub_param2 = $('#asset_space').val();
                sub_param3 = $('#asset_element').val();
                if (pageTypeCode != '') {
                    optionalParams.page_type = pageTypeCode;
                }
                if (adset != '') {
                    optionalParams.adset = adset;
                }
                if (sub_param1 != '') {
                    optionalParams.sub_param1 = sub_param1;
                }
                if (sub_param2 != '') {
                    optionalParams.sub_param2 = sub_param2;
                }
                if (sub_param3 != '') {
                    optionalParams.sub_param3 = sub_param3;
                }
                console.log(optionalParams);
                var optionalParamsQ = $.param(optionalParams)
                console.log('拼接后的optional_params_query:'+optionalParamsQ);
                if (originLink.indexOf("?") >= 0) {
                    var lastQ = '&'+mustParamsQ;
                } else {
                    var lastQ = '?'+mustParamsQ;
                }
                if (optionalParamsQ != '') {
                    lastQ += '&' + optionalParamsQ;
                }
                channelOneId = $('select[name="channel_one_id"] option:selected').val();
                console.log(channelOneId);
                if (channelOneId != $iChannelOneIdShare) {
                    lastQ += '&os=__OS__&ip=__IP__&ua=__UA__&ts=__TS__';   
                }
                return originLink + lastQ;
            }

        SCRIPT;
    }

    public function getChannelCode(Request $request) {
        $sChannelCode = AttributionLink::getLastId()+1;
        return response()->json([
            'status' => 'success',
            'message' => '自动生成成功',
            'data' => $sChannelCode
        ]);
    }

    public function getChannelSelectData(Request $request) {
        $channelid = (int)$request->get('q', 0);
        return ChannelService::getChannelSubSelectOptionsWithCode($channelid);
    }

    public function getChannelName(Request $request) {
        $sChannelIds = $request->get('channel_ids');
        $aChannelId = explode(',', $sChannelIds);
        $aChannelCodeList = Channel::getCodeListByIds($aChannelId);
        $aChannelCodeList = array_column($aChannelCodeList, 'code', 'id');
        return response()->json([
            'status' => 'success',
            'message' => '获取成功',
            'data' => $aChannelCodeList
        ]);
    }

    public function save(Request $request) {
        $request = $request->all();
        if (empty($request['target_link'])) {
            $error = new MessageBag(['title' => '请先生成归因链接～']);
            return back()->with(compact('error'));
        }
        if (empty($request['channel_one_id'])) {
            $error = new MessageBag(['title' => '投放大类未选择～']);
            return back()->with(compact('error'));
        }
        if (empty($request['channel_two_id'])) {
            $error = new MessageBag(['title' => '投放渠道未选择～']);
            return back()->with(compact('error'));
        }
        if (empty($request['channel_three_id'])) {
            $error = new MessageBag(['title' => '投放位置未选择～']);
            return back()->with(compact('error'));
        }
        if (empty($request['channel_code'])) {
            $error = new MessageBag(['title' => '渠道编码未选择～']);
            return back()->with(compact('error'));
        }
        if (mb_strlen($request['reason']) > 255) {
            $error = new MessageBag(['title' => '活动理由超长了哦～']);
            return back()->with(compact('error'));
        }
        $data = [
            'channel_one_id' => $request['channel_one_id'],
            'channel_two_id' => $request['channel_two_id'],
            'channel_three_id' => $request['channel_three_id'],
            'asset_type_id' => $request['asset_type_id'],
            'asset_form' => $request['asset_form'],
            'asset_theme' => $request['asset_theme'],
            'asset_space' => $request['asset_space'],
            'asset_element' => $request['asset_element'],
            'origin_link' => $request['origin_link'],
            'reason' => $request['reason'],
            'admin_id' => Admin::user()->id,
        ];
        $aChannelList = Channel::getCodeListByIds([$request['channel_one_id'], $request['channel_two_id'], $request['channel_three_id']]);
        $aChannelCodeList = array_column($aChannelList, 'code', 'id');
        $aChannelNameList = array_column($aChannelList, 'name', 'id');
        $data['channel_one_name'] = $aChannelNameList[$request['channel_one_id']];
        $data['channel_two_name'] = $aChannelNameList[$request['channel_two_id']];
        $data['channel_three_name'] = $aChannelNameList[$request['channel_three_id']];
        $data['channel_one_code'] = $aChannelCodeList[$request['channel_one_id']];
        $data['channel_two_code'] = $aChannelCodeList[$request['channel_two_id']];
        $data['channel_three_code'] = $aChannelCodeList[$request['channel_three_id']];
        if (!empty($request['asset_type_id'])) {
            $assetInfo = Assets::get('*', ['id' => $request['asset_type_id']]);
            $data['asset_type_name'] = $assetInfo['name'];
            $data['asset_type_code'] = $assetInfo['code'];
        }
        $sChannelCode = $request['channel_code'];
        if ($request['channel_one_id'] == self::CHANNEL_ONE_ID_SHARE) {
            $sChannelCode = $data['channel_one_code'] .'-'.$data['channel_two_code'].'-'.$data['channel_three_code'].'-'.(AttributionLink::getLastId()+1);
        }
        $data['channel_code'] = $sChannelCode;
        $data['target_link'] = self::getTargetLink($data);

        // 生成短链
        try {
            $aShortRes = $this->_getShortLinkId($data['target_link'], $data['channel_two_name'].'('.$data['channel_two_code'].')');
        } catch (\Exception $e) {
            $error = new MessageBag(['title' => $e->getMessage()]);
            return back()->with(compact('error'));
        }
        $data['short_link_id'] = $aShortRes['short_link_id'];
        $data['short_link'] = self::SHORT_PREFIX . $aShortRes['short_link'];
        if (!AttributionLink::addInfo($data)) {
            $error = new MessageBag(['title' => '归因链接记录保存失败']);
            return back()->with(compact('error'));
        }
        $success = new MessageBag(['title' => '保存成功']);
        return redirect('/admin/adServing/attribution')->with(compact('success'));
    }

    public static function getTargetLink($aParams) {
        $sOriginLink = $aParams['origin_link'];
        $aMustParams = [];
        if (!empty($aParams['channel_one_code'])) {
            $aMustParams['media_source'] = $aParams['channel_one_code'];
        }
        if (!empty($aParams['channel_two_code'])) {
            $aMustParams['channel'] = $aParams['channel_two_code'];
        }
        if (!empty($aParams['channel_three_code'])) {
            $aMustParams['location'] = $aParams['channel_three_code'];
        }
        if (!empty($aParams['channel_code'])) {
            $aMustParams['detail_name'] = $aParams['channel_code'];
        }
        $sMustParam = http_build_query($aMustParams);
        $aOptionParams = [];
        if (!empty($aParams['asset_type_code'])) {
            $aOptionParams['page_type'] = $aParams['asset_type_code'];
        }
        if (!empty($aParams['asset_form'])) {
            $aOptionParams['adset'] = $aParams['asset_form'];
        }
        if (!empty($aParams['asset_theme'])) {
            $aOptionParams['sub_param1'] = $aParams['asset_theme'];
        }
        if (!empty($aParams['asset_space'])) {
            $aOptionParams['sub_param2'] = $aParams['asset_space'];
        }
        if (!empty($aParams['asset_element'])) {
            $aOptionParams['sub_param3'] = $aParams['asset_element'];
        }
        if (strpos($sOriginLink, '?') !== false) {
            $sLastQ = '&' . $sMustParam;
        } else {
            $sLastQ = '?' . $sMustParam;
        }
        if (!empty($aOptionParams)) {
            $sOptionParams = http_build_query($aOptionParams);
            $sLastQ .= '&' . $sOptionParams;
        }
        // 对外分享页不拼接额外参数
        if ($aParams['channel_one_id'] != self::CHANNEL_ONE_ID_SHARE) {
            $sLastQ .= '&os=__OS__&ip=__IP__&ua=__UA__&ts=__TS__';
        }
        return $sOriginLink . $sLastQ;
    }

    private function _getShortLinkId($sUrl, $sDepartment) {
        $data = [
            'long_link' => $sUrl,
            'short_link' => '',
            'reason' => '归因链接',
            'department' => $sDepartment,
            'address' => '',
            'admin_id' => Admin::user()->id,
            'addtime' => time(),
            'status' => 1,
        ];
        if (mb_strlen($sUrl) > 2000) {
            throw new \Exception('链接长度超过2000了哦～');
        }
        $insertId = ShortLink::insertData($data);
        if (!$insertId) {
            throw new \Exception('创建短连接失败');
        }
        $sShortLink = ShortLink::createShortLink($insertId, $data['long_link'], $data['long_link_app']);

        return ['short_link_id' => $insertId, 'short_link' => $sShortLink];
    }

    public function del(Request $request, $id) {
        if (!AttributionLink::updateInfo(['admin_id' => Admin::user()->id, 'data_status' => AttributionLink::STATUS_DELETE], ['id' => $id])) {
            return response()->json([
                'status' => false,
                'message' => "删除失败",
            ]);
        }
        return response()->json([
            'status' => false,
            'message' => "删除成功",
        ]);
    }
}
